home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug172 / out1.c < prev    next >
C/C++ Source or Header  |  1986-02-05  |  13KB  |  355 lines

  1. /*
  2.   HEADER: CUG     nnn.nn;
  3.   TITLE:     LEX - A Lexical Analyser Generator
  4.   VERSION:     1.0 for IBM-PC
  5.   DATE:      Jan 30, 1985
  6.   DESCRIPTION:     A Lexical Analyser Generator. From UNIX
  7.   KEYWORDS:     Lexical Analyser Generator YACC C PREP
  8.   SYSTEM:     IBM-PC and Compatiables
  9.   FILENAME:      OUT1.C
  10.   WARNINGS:     This program is not for the casual user. It will
  11.          be useful primarily to expert developers.
  12.   CRC:         N/A
  13.   SEE-ALSO:     YACC and PREP
  14.   AUTHORS:     Scott Guthery 11100 leafwood lane Austin, TX 78750
  15.   COMPILERS:     DESMET-C
  16.   REFERENCES:     UNIX Systems Manuals
  17. */
  18. /*
  19.  * Copyright (c) 1978 Charles H. Forsyth
  20.  *
  21.  * Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for smaller size
  22.  *                           01 -- Removed ending() function code from here
  23.  *                                  to lex.c, so ytab.c code could share the
  24.  *                                  same overlay region as this module.
  25.  *                           02 -- Removed nfaprint(), llactr(), newcase(),
  26.  *                                  cclprint(), chprint() and setline(),
  27.  *                                  the rest of this can share an overlay.
  28.  *                                  They're in 'out2.c'. This is now 'out1.c'.
  29.  *          29-May-81 Bob Denny -- More extern hacking for RSX overlaying.
  30.  *          19-Mar-82 Bob Denny -- New compiler and library
  31.  *          03-May-82 Bob Denny -- Final touches, remove unreferenced autos
  32.  *          28-Aug-82 Bob Denny -- Put "=" into table initializers to make
  33.  *                                  new compiler happy. Add "-s" code to
  34.  *                                  supress "#include <stdio.h>" in output.
  35.  *                                  Tables output 8 values/line instead of
  36.  *                                  16.  Overran R.H. edge on 3 digit octals.
  37.  *                                  Change output format for readability.
  38.  *          31-Aug-82 Bob Denny -- Add lexswitch( ...) to llstin so table
  39.  *                                  name selected by -t switch is automatically
  40.  *                                  switched-to at yylex() startup time.  Removed
  41.  *                                  hard reference to "lextab" from yylex();
  42.  *                                  This module generates extern declaration
  43.  *                                  for forward reference.
  44.  *          14-Apr-83 Bob Denny -- Add VAX11C support.  Remove usage of remote
  45.  *                                  formats (damn!) not supported on VAX-11 C.
  46.  *                                 Use "short int" for 16-bit table items under
  47.  *                                  VAX-11 C to save size.
  48.  *                                 Contitional out flaky debug code.  Probably
  49.  *                                  related to non-functional minimization.
  50.  *            20-Nov-83 Scott Guthery -- Adapt for IBM PC & DeSmet C
  51.  *            26-Dec-83 Scott Guthery -- Removed "extern FILE lexin" from llstin
  52.  *                                       code and put it lex.h.
  53.  */
  54.  
  55. /*
  56.  * lex -- output human- and machine-readable tables
  57.  */
  58.  
  59. #include <stdio.h>
  60. #include "lexlex.h"
  61.  
  62. extern char *ignore;
  63. extern char *illeg;
  64. extern char *breakc;
  65. extern int nlook;
  66.  
  67. char strdec1[] = "\nstruct lextab %s =\t{\n";
  68. char strdec2[] = "\t\t\t%d,\t\t/* Highest state */\n";
  69. char strdec3[] = "\t\t\t_D%s\t/* --> \"Default state\" table */\n";
  70. char strdec4[] = "\t\t\t_N%s\t/* --> \"Next state\" table */\n";
  71. char strdec5[] = "\t\t\t_C%s\t/* --> \"Check value\" table */\n";
  72. char strdec6[] = "\t\t\t_B%s\t/* --> \"Base\" table */\n";
  73. char strdec7[] = "\t\t\t%d,\t\t/* Index of last entry in \"next\" */\n";
  74. char strdec8[] = "\t\t\t%s,\t\t/* --> Byte-int move routine */\n";
  75. char strdec9[] = "\t\t\t_F%s\t/* --> \"Final state\" table */\n";
  76. char strdec10[] = "\t\t\t_A%s\t/* --> Action routine */\n";
  77. char strdec11[] = "\n\t\t\t%s%s\t/* Look-ahead vector */\n";
  78.  
  79.  
  80. char ptabnam[] = { "         " };
  81.  
  82. /*
  83.  * Print the minimised DFA, and at the same time, construct the vector which
  84.  * indicates final states by associating them with their translation index.
  85.  * (DFA printout supressed ifndef DEBUG.)
  86.  */
  87. dfaprint()
  88. {
  89.         register struct move *dp;
  90.         register struct dfa *st;
  91.         register i;
  92.         int fi, k, l;
  93.  
  94.         vstart("LL16BIT _F%s", tabname);
  95. #ifdef DEBUG
  96.         fprintf(lexlog, "\nMinimised DFA for complete syntax\n");
  97. #endif
  98.         for (i = 0; i < ndfa; i++) {
  99. #ifdef DEBUG
  100.                 fprintf(lexlog, "\nstate %d", i);
  101. #endif
  102.                 st = &dfa[i];
  103.                 k = -1;
  104.                 if (fi = st->df_name->s_final) {
  105.                         k = nfa[fi].n_trans - trans;
  106. #ifdef DEBUG
  107.                         fprintf(lexlog, " (final %d[%d])", fi, k);
  108. #endif
  109.                         if (nfa[fi].n_flag&FLOOK) {
  110.                                 k |= (nfa[fi].n_look+1)<<11;
  111. #ifdef DEBUG
  112.                                 fprintf(lexlog, " restore %d", nfa[fi].n_look);
  113. #endif
  114.                         }
  115.                 }
  116.                 if (l = st->df_name->s_look)
  117. #ifdef DEBUG
  118.                         fprintf(lexlog, " look-ahead %o", l);
  119. #else
  120.                         ;
  121. #endif
  122.                 vel(" %d,", k);
  123. #ifdef MINIM_OK
  124.                 k = st->df_name->s_group->s_els[0];
  125.                 if (k!=i) {
  126.                         fprintf(lexlog, " deleted\n");
  127.                         continue;
  128.                 }
  129.  
  130.                 fprintf(lexlog, "\n");
  131.                 for (dp = st->df_base; dp < st->df_max; dp = range(st, dp))
  132.                 if (st->df_default)
  133.                       fprintf(lexlog, "\t.\tsame as %d\n", st->df_default-dfa);
  134. #endif
  135.         }
  136.         vel(" %d,", -1);        /* blocking state */
  137.  
  138.         vend();
  139. }
  140.  
  141. #ifdef MINIM_OK
  142.  
  143. range(st, dp)
  144. register struct dfa *st;
  145. register struct move *dp;
  146. {
  147.         int low, high, last;
  148.         struct set *s;
  149.         register a;
  150.  
  151.         while (dp < st->df_max && dp->m_check!=st)
  152.                 dp++;
  153. /***************************************************
  154.  * This always returns given the above statement ! *
  155.  ***************************************************/
  156.         if (dp >= st->df_max)
  157.                 return(dp);
  158.  
  159.         low = dp - st->df_base;
  160. /*
  161.         s = dp->m_next->s_group->s_els[0];
  162. */
  163.         s = dp->m_next;
  164.         for (last = low-1; dp < st->df_max &&
  165.                            dp->m_check==st &&
  166.                            (a = dp - st->df_base)==last+1 &&
  167. /*
  168.                            dp->m_next->s_state->s_els[0]==s; dp++)
  169. */
  170.                            dp->m_next==s; dp++)
  171.                 last = a;
  172.         high = last;
  173.         fprintf(lexlog, "\t");
  174.         if (high==low)
  175.                 chprint(low);
  176.         else {
  177.                 fprintf(lexlog, "[");
  178.                 if (high-low > 4) {
  179.                         chprint(low);
  180.                         fprintf(lexlog, "-");
  181.                         chprint(high);
  182.                 } else {
  183.                         while (low<=high)
  184.                                 chprint(low++);
  185.                 }
  186.                 fprintf(lexlog, "]");
  187.         }
  188.         if (s->s_state==NULL)
  189.                 fprintf(lexlog, "\tNULL\n"); else
  190.                 fprintf(lexlog, "\t%d\n", s->s_state-dfa);
  191.         return(dp);
  192. }
  193. #endif
  194.  
  195. heading()
  196. {
  197.         char *ver;
  198.         fprintf(llout,
  199.          "/*\n * Created by IBM PC LEX from file \"%s\"\n", infile);
  200.         if(sflag == 0)                  /* If "standalone" switch off */
  201.                 {
  202.                 fprintf(llout,
  203.                         " *\t- for use with standard I/O\n */\n");
  204.                 fprintf(llout, "\n#include <stdio.h>\n");
  205.                 }
  206.         else
  207.                 fprintf(llout, " *\t- for use with stand-alone I/O\n */\n");
  208.  
  209.         fprintf(llout, "#include <lex.h>\n");
  210.         fprintf(llout, "#define LL16BIT int\n");
  211.         fprintf(llout, "extern int _lmov%c();\n",
  212.                         (ndfa <= 255) ? 'b' : 'i');
  213.         fprintf(llout, "extern struct lextab *_tabp;\n");
  214.         fprintf(llout, "int lexval, yyline;\n");
  215.         fprintf(llout, "char lbuf[], *llend;\n");
  216. }
  217.  
  218. dfawrite()
  219. {
  220.         register struct move *dp;
  221.         register i, a;
  222.         struct dfa *st, *def;
  223.         struct set *xp;
  224.         char *xcp;
  225.  
  226.         setline();
  227.         fprintf(llout,
  228.                 "\n#define\tLLTYPE1\t%s\n", ndfa<=255? "char": "LL16BIT");
  229.         vstart("LLTYPE1 _N%s", tabname);
  230.         for (i = 0; i <= llnxtmax; i++)
  231.                 if (xp = move[i].m_next)
  232.                         vel(" %d,", xp->s_state-dfa); else
  233.                         vel(" %d,", ndfa);
  234.         vend();
  235.  
  236.         vstart("LLTYPE1 _C%s", tabname);
  237.         for (i = 0; i <= llnxtmax; i++)
  238.                 if (st = move[i].m_check)
  239.                         vel(" %d,", st-dfa); else
  240.                         vel(" %d,", -1);
  241.         vend();
  242.         vstart("LLTYPE1 _D%s", tabname);
  243.         for (i = 0; i < ndfa; i++)
  244.                 if (def = dfa[i].df_default)
  245.                         vel(" %d,", def-dfa); else
  246.                         vel(" %d,", ndfa); /* refer to blocking state */
  247.         vend();
  248.         vstart("LL16BIT _B%s", tabname);
  249.         for (i = 0; i < ndfa; i++)
  250.                 if (dp = dfa[i].df_base)
  251.                         vel(" %d,", dp-move); else
  252.                         vel(" %d,", 0);
  253.         vel(" %d,", 0); /* for blocking state */
  254.         vend();
  255.         if (nlook) {
  256.                 fprintf(llout, "char    *llsave[%d];\n", nlook);
  257.                 vstart("LL16BIT _L%s", tabname);
  258.                 a = nlook<=NBPC? NCHARS-1: -1;
  259.                 for (i = 0; i < ndfa; i++)
  260.                         vel(" 0%o,", dfa[i].df_name->s_look&a);
  261.                 vel(" %d,", 0);
  262.                 vend();
  263.         }
  264.         dospccl(ignore, "LLIGN", "X");
  265.         dospccl(breakc, "LLBRK", "Y");
  266.         dospccl(illeg, "LLILL", "Z");
  267.  
  268.         strcpy(ptabnam, tabname); strcat(ptabnam,",");
  269.         fprintf(llout, strdec1, tabname);
  270.         fprintf(llout, strdec2, ndfa);
  271.         fprintf(llout, strdec3, ptabnam);
  272.         fprintf(llout, strdec4, ptabnam);
  273.         fprintf(llout, strdec5, ptabnam);
  274.         fprintf(llout, strdec6, ptabnam);
  275.         fprintf(llout, strdec7, llnxtmax);
  276.         fprintf(llout, strdec8, ndfa<=255?"_lmovb":"_lmovi");
  277.         fprintf(llout, strdec9, ptabnam);
  278.         fprintf(llout, strdec10, ptabnam);
  279.         fprintf(llout, strdec11, nlook?"_L":"", nlook?ptabnam:"NULL,   ");
  280.         refccl(ignore, "Ignore", "X");
  281.         refccl(breakc, "Break", "Y");
  282.         refccl(illeg, "Illegal", "Z");
  283.         fprintf(llout, "\t\t\t};\n");
  284.         if(sflag == 0)                  /* If stdio flavor */
  285.                 {
  286.                 fprintf(llout, "\n/* Standard I/O selected */\n");
  287.  
  288.                 fprintf(llout, "FILE lexin;\n\n");
  289.  
  290.                 fprintf(llout, "llstin()\n   {\n   if(lexin == NULL)\n");
  291.                 fprintf(llout, "      lexin = stdin;\n");
  292.                 }
  293.         else                            /* Stand-alone flavor */
  294.                 {
  295.                 fprintf(llout, "\n/* Stand-alone selected */\n");
  296.                 fprintf(llout, "\llstin()\n   {\n");
  297.                 }
  298.         fprintf(llout, "   if(_tabp == NULL)\n");
  299.         fprintf(llout, "      lexswitch(&%s);\n   }\n\n", tabname);
  300.         fclose(llout);
  301. }
  302.  
  303. dospccl(cp, s, tag)
  304. register char *cp;
  305. char *s, *tag;
  306. {
  307.         register n;
  308.         char cclnam[16];
  309.  
  310.         if (cp==0)
  311.                 return;
  312.         fprintf(llout, "#define\t%s\t%s\n", s, tag);
  313.         strcpy(cclnam, tag); strcat(cclnam, tabname);
  314.         vstart("char _%s", cclnam);
  315.         for (n = sizeof(ccls[0]); n--;)
  316.  
  317.                 vel(" 0%o,", *cp++&0377);
  318.         vend();
  319. }
  320.  
  321. refccl(cp, nm, tag)
  322. char *cp, *nm, *tag;
  323. {
  324.         if (cp==0)
  325.                 fprintf(llout, "\t\t\t0,\t\t/* No %s class */\n", nm);
  326.         else
  327.                 fprintf(llout, "\t_%s%s,\t/* %s class */\n", tag, tabname, nm);
  328. }
  329.  
  330. int     vnl;
  331.  
  332. vstart(fmt, str)
  333. char *fmt;
  334. char *str;              /*** WATCH IT ***/
  335. {
  336.         vnl = 0;
  337.         putc('\n', llout);
  338.         fprintf(llout, fmt, str);
  339.         fprintf(llout, "[] =\n   {\n  ");
  340. }
  341.  
  342. vend()
  343. {
  344.         fprintf(llout, "\n   };\n");
  345. }
  346.  
  347. vel(fmt, val)
  348. char *fmt;
  349. int val;                /*** WATCH IT ***/
  350. {
  351.         fprintf(llout, fmt, val);
  352.         if ((++vnl&07)==0)
  353.                 fprintf(llout, "\n  ");
  354. }
  355.